
var Utils = DAS.Utils;
var Class = Utils.Class;


var orks = {
	_archetype:'Orks',
	HQ: {
		Warboss: {
			_cost: 90,
			Klaw: {
				_cost: 25,
			},
			Cybork_body: {
				_cost: 30,
			}
		},
	},
	TROOPS: {
		Boyz_mob: {
			Boyz: {
				_cost: 6,
				Shootas: { _cost: 0 },
				Stikkboms: { _cost: 1 },					
			},
			Big_shootas: {
				_cost: 5,
			},
			Rokkits: {
				_cost: 10,
			},
			Nob: {
				_cost: 10,
				Klaw: { _cost: 25 },
			},
		}
	}
}

var orkarmy = {
	_archetype: 'Orks',
	_type: 'Orks',	
	_name:'Mah Awks',
	_count: 1,
	_members: [ 
		{
			_type: 'HQ',
			_count: 1,
			_members: [ 
				{
					_type: 'Warboss',
					_count: 1,
					_members: [ 
						{ 
							_type: 'Klaw',
							_count: 2,
						},
						{ 
							_type: 'Cybork_body',
							_count: 1,
						},
					],
					
				},
			],
		},
	],
}



var editstack = [];
var armybase

function nextView( fn ) {
	editstack.push( fn )
	fn()
	armybase.updateCosts()
	$.Storage.set('Orks', JSON.stringify(orks))
	$.Storage.set('myorkarmy', JSON.stringify(orkarmy))
}

function lastView() {
	editstack.pop()
	editstack[editstack.length-1]()
	armybase.updateCosts()
	$.Storage.set('Orks', JSON.stringify(orks))
	$.Storage.set('myorkarmy', JSON.stringify(orkarmy))
}

function refreshView() {
	editstack[editstack.length-1]()
	armybase.updateCosts()
	$.Storage.set('Orks', JSON.stringify(orks))
	$.Storage.set('myorkarmy', JSON.stringify(orkarmy))
}

//function Node( data, archetype ) {
var Node = Class( function( parent, data, archetype ) {
	//public
	this.parent = parent
	this.data = data
	this.archetype = archetype

	this.title = data._type.replace('_',' ')
	this.members = [];
	
	//add children
	if (!this.data._members) this.data._members = [];
	
	for (var d, i=0; d=data._members[i]; i++) {
		this.addMember( d, d._type);
	}

	if (this.data._members.length != this.members.length) throw('member mismatch!');
})

Node.prototype.checkTitle = function(archetype, newtype) {
	if (this.archetype == archetype) {
		this.data._type = newtype
		this.title = newtype.replace('_',' ')
		
	}
	for (var m, i=0; m=this.members[i]; i++)
		m.checkTitle( archetype, newtype )
}

Node.prototype.addMissingArchetypes = function() {
	for (var k in this.archetype) {
		if (k.slice(0,1)=='_')
			continue;
			
		var found = 0;
		for (var m, i=0; m=this.members[i]; i++) {
			if (m.data._type == k)
				found++;
		}
		if (!found) {
			this.addMember( null, k );
		}
	}
}


Node.prototype.removeEmptyMembers = function() {
	for (var d, i=0; d=this.data._members[i]; i++) {
		if (d._count == 0) {
			this.removeMember(i)
			i--;
		}
	}
}


Node.prototype.addMember = function(data, type) {
	if (!data) {
		data = { 
			_type: type,
			_count: 0 
		}
		this.data._members.push(data)
	}
	var new_node = new Node( this, data, this.archetype[type] );
	this.members.push( new_node )

	return new_node
}

Node.prototype.removeMember = function(index) {
	this.data._members.splice(index,1)
	this.members.splice(index,1)
	if (this.data._members.length != this.members.length) throw('member mismatch!');
}

Node.prototype.newArchetype = function( title, cost ) {
	var type = $.trim(title).replace(' ','_')
	
	//matches existing archetype?
	//can duplicate members this way
	var archetype = null
	for (var k in this.archetype) {
		if (k.toLowerCase() == type.toLowerCase()) {
			type = k
			archetype = this.archetype[k]
			break
		}
	}
	//new archetype
	if (!archetype) {
		this.archetype[type] = {
			_cost: cost || 0,
		}	
	}
	var n = this.addMember( null, type )
	n.data._count = 1		
}


Node.prototype.isContainer = function() {
	for (var k in this.archetype)
		if (k.slice(0,1)!='_') 
			return true
		
	return false
}

Node.prototype.incrementCount = function( dn ) {
	var n = this.data._count + dn
	if (n < 0) 
		n=0;
	this.setCount( n )
}

Node.prototype.setCount = function( n ) {
	if (n!=undefined)
		this.data._count = n
		
	this.$el.children('.count').html( this.data._count + ' x ' )
	return this
}

Node.prototype.setCost = function( n ) {
	this.archetype._cost = n
	this.updateCosts()
}

Node.prototype.getCostEach = function() {
	var cost = this.archetype._cost || 0
	
	for (var m, i=0; m=this.members[i]; i++) {
		cost += m.updateCosts();
	}	
	return cost
}

Node.prototype.updateCosts = function() {
	var cost = this.getCostEach()
	cost *= this.data._count
	
	this.$el.children('.cost').html( cost + ' pts' )	
	return cost
}


Node.prototype.renderAsFlag = function() {
	this.$el = $('<div class="node flag">')
	this.removeEmptyMembers()
	
	var h = ''
	h += '<span class="count"></span>';
	h += '<span class="title">'+this.title+'</span>'
	this.$el.html(h)
	
	this.setCount()//.setCost().editOnClick().wireEditButtons()

	if (this.data._count == 1)
		this.$el.children('.count').hide()

	return this.$el
}


Node.prototype.renderAsContainer = function() {
	this.$el = $('<div class="node container">')
	this.removeEmptyMembers()
	
	var h = '';
	h += '<div style="float:right" class="cost"></div>';
	h += '<span class="count"></span>';
	h += '<span class="title">'+this.title+'</span>'
	h += '<span class="flags_wrap"> (<span class="flags"></span>) </span>';
	h += '<ul class="containers"></ul>';
	this.$el.html(h)


	var $containers = this.$el.children('.containers').hide();
	var $flags_wrap = this.$el.children('.flags_wrap').hide();
	var $flags = $flags_wrap.children('.flags');
	
	for (var m, i=0; m=this.members[i]; i++) {
		if (m.isContainer()) {
			$containers.show().append( m.renderAsContainer() );
		}
		else {
			if ($flags.children().length > 0) 
				$flags.append(', ');
			$flags.append( m.renderAsFlag() );
			$flags_wrap.show();
		}
	}
	
	this.setCount().editOnClick()//.wireEditButtons()
	
	if (this.data._count == 1)
		this.$el.children('.count').hide()
	
	return this.$el;
}



Node.prototype.renderAsEditChild = function() {
	this.$el = $('<div class="node line">')
	this.removeEmptyMembers()
	
	var h = '';
	h += '<input style="float:right" type="button" class="plus" value=" + " />';
	h += '<input style="float:right" type="button" class="minus" value=" - " />';
	h += '<div style="float:right" class="costeach"></div>';
	h += '<span style="float:right; display:block; padding-right:0.3em;" class="count"></span>';
	h += '<span class="title">'+this.title+'</span>'
	h += '<span class="flags_wrap"> (<span class="flags"></span>) </span>';
	this.$el.html(h)
	
	this.$el.children('.costeach').html(this.getCostEach())

	
	var $flags_wrap = this.$el.children('.flags_wrap').hide();
	var $flags = $flags_wrap.children('.flags');
	
	for (var m, i=0; m=this.members[i]; i++) {
		if ($flags.children().length > 0)
			$flags.append(', ');
		$flags.append( m.renderAsFlag() );
		$flags_wrap.show();
	}
	
	this.setCount().editOnClick().wireEditButtons()
	return this.$el;
}


Node.prototype.renderForEdit = function() {
	this.$el = $('<div class="node editing">')
	this.removeEmptyMembers()
	
	var h = '';
	h += '<div style="float:right" class="cost"></div>';
	h += '<input style="display:block; float:right" class="editcost" />';
//	h += '<input style="float:right" type="button" class="plus" value=" + " />';
//	h += '<input style="float:right" type="button" class="minus" value=" - " />';
//	h += '<span class="count"></span>';
	h += '<input type="text" class="edittitle" value="'+this.title+'" />';
	h += '<ul class="members"></ul>';
	h += '<input style="display:block; float:right" type="button" class="done" value="Done" />';
	h += '<input type="text" class="newoptiontitle" />';
	h += '<input type="text" class="newoptioncost" />';
	h += '<input type="button" class="addoption" value="Add" />';
	this.$el.html(h)

	this.$el.children('.editcost').val(this.archetype._cost);
	this.$members = this.$el.children('.members');	

	this.addMissingArchetypes();
	
	for (var m, i=0; m=this.members[i]; i++) {
		this.$members.append( m.renderAsEditChild() );
	}
	
	this.setCount().wireEditButtons()
	return this.$el;
}





Node.prototype.editOnClick = function() {
	var self = this;
	self.$el.on('click', function(e) {
		
		nextView(function() {
			$('#armyedit').empty().append( self.renderForEdit() );
		})
	
		return e.preventDefault(), false;
	})
	return this;
}

Node.prototype.wireEditButtons = function() {
	var self = this;

	//increment count	
	self.$el.children('input.plus').on('click', function(e) {
		self.incrementCount( 1 )
		armybase.updateCosts()
		return e.preventDefault(), false;
	});
	self.$el.children('input.minus').on('click', function(e) {
		self.incrementCount( -1 );		
		armybase.updateCosts()
		return e.preventDefault(), false;
	});

	//done
	self.$el.children('input.done').on('click', function(e) {
		//end edit mode
		setTimeout(lastView, 0)
		return e.preventDefault(), false;
	});
	
	//addoption
	self.$el.children('input.addoption').on('click', function(e) {
		//get new option title
		var title = self.$el.children('.newoptiontitle').val()
		var cost = self.$el.children('.newoptioncost').val()
		cost = parseInt(cost) || 0
		self.newArchetype( title, cost )
		setTimeout(refreshView, 0)
		return e.preventDefault(), false;
	});
	
	//editcost
	self.$el.children('input.editcost').on('change keyup', function(e) {
		var n = self.$el.children('input.editcost').val()
		n = parseInt(n)
		if (!n) n = 0;
		self.$el.children('input.editcost').val(n)
		
		self.setCost(n)		
		return e.preventDefault(), false;
	});
	
	//edittitle
	self.$el.children('input.edittitle').on('change', function(e) {
		var newtype = self.$el.children('input.edittitle').val()
		newtype = $.trim(newtype).replace(' ','_')
		oldtype = self.title.replace(' ','_')
		
		if (newtype && newtype != oldtype) {
			if (self.parent) {
				self.parent.archetype[newtype] = self.parent.archetype[oldtype]
				delete self.parent.archetype[oldtype]
			}
			else 
				self.archetype._archetype = newtype

			armybase.checkTitle( self.archetype, newtype);			
		}
	});
	
	return this;
}






$(function(){
//	$.Storage.set('Orks', JSON.stringify(orks))
//	$.Storage.set('myorkarmy', JSON.stringify(orkarmy))
//	
	orkarmy = JSON.parse( $.Storage.get('myorkarmy') || '' )
	orks = JSON.parse( $.Storage.get('Orks')  || '' )
	
	armybase = new Node( null, orkarmy, orks )
	nextView(function() {
		$('#armyedit').empty().append( armybase.renderAsContainer() );
	})
	
});





